package com.qf.fmall2203.user.controller;

import cn.hutool.jwt.JWT;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.qf.fmall2203.user.entity.Users;
import com.qf.fmall2203.user.service.IUsersService;
import com.qf.fmall2203.user.vo.UserRegistVo;
import com.qf.fmall2203.utils.Constants;
import com.qf.fmall2203.utils.ResultVo;
import lombok.extern.slf4j.Slf4j;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.subject.Subject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import javax.validation.Valid;
import java.util.Date;

/**
 * <p>
 * 用户  前端控制器
 * </p>
 *
 * @author dongjl
 * @since 2023-02-13
 */
@CrossOrigin
@RestController
@RequestMapping("/user")
@Slf4j
public class UsersController {

    @Autowired
    IUsersService usersService;

    @GetMapping("/login")
    public ResultVo login(String username,String password) throws Exception {

        log.debug("入参为:username={},password={}",username,password);
        if (username==null || username.equals("")){
            throw new Exception("用户名不能为空");
        }
        if (password==null || password.equals("")){
            throw new Exception("密码不能为空");
        }

        // 登录逻辑交给 shiro
        final Subject subject = SecurityUtils.getSubject();  // shiro中的当前用户对象
        subject.login(new UsernamePasswordToken(username,password));

        // 如何获取 数据库中数据对应 user 对象呢
        final Users user = (Users) subject.getPrincipal();

        // 创建 jwt token，并且把需要保存的数据放到 token中
        // User对象 ---->  json字符串
        final ObjectMapper objectMapper = new ObjectMapper(); // jackson类库提供的 json转换器对象

        final String userJson = objectMapper.writeValueAsString(user);

        final String token = JWT.create().setPayload("sub", userJson)
                .setExpiresAt(new Date(System.currentTimeMillis() + 1000 * 60 * 60 * 24 * 14)) // token有效期 两周
                .setIssuer("fmall")  // token是由谁签发的
                .setKey(Constants.SECRET.getBytes("utf-8"))
                .sign();

        final ResultVo ok = ResultVo.ok(user);

        // 设置 token 到 msg字段，返回给前端
        ok.put("msg",token);

        // 登录成功
        return ok;


    }

    /**
     * 注册接口
     * @param userRegistVo
     * @return
     * @throws Exception
     */
    @PostMapping("/regist")
    public ResultVo regist(@Valid @RequestBody UserRegistVo userRegistVo) throws Exception {
        log.debug("入参为userRegistVo={}",userRegistVo);
        usersService.regist(userRegistVo);

        // 如果上面的代码没有异常，则安装注册成功进行返回
        return ResultVo.ok();
    }


    @GetMapping("/test")
    public String test(){
        return "test";
    }

    @GetMapping("/get/{id}")
    public Users getUser(@PathVariable("id") Integer id){
        final Users users = usersService.getById(id);
        return users;
    }




}
